/* $RCSFile: Login.ascx.cs $
 * Apache license v2 2011 by Christian Surieux
 * $Source: ?/AddonNice/PageModules/Login/Login.ascx.cs $
 * $log$
 * Revision 20 2010/08/09 10:51:21  christian.surieux
 *   Added Log comment to all .aspx .ascx .master files
 * Revision 19 2010/08/09 09:43:55  christian.surieux
 *   Added Log to cs sources files
 * Revision 6 2010/08/06 19:56:25  christian.surieux
 *   Added Log to All cs files
 */

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Configuration;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Globalization;

using AddonNice.Core;
using AddonNice.Diagnostics;
using AddonNice.UI.WebControls;
using AddonNice.Security;
using AddonNice.Authentication;
using AddonNice.Settings;
using AddonNice.UI;
using AddonNice.Design;
using AddonNice.UI.DataTypes;
using AddonNice.Configuration;
using AddonNice.Configuration.Settings;
using AddonNice.UI.Design;
using AddonNice.Helpers;

using AddonNice.CRMWrapper;

using Path2 =   AddonNice.Settings.Path;
using Trace2    =   System.Diagnostics.Trace;

namespace AddonNice.PageModules.Login
{

 	#region Local TraceSwitch 
	public class LoginTrace : ADNTraceSwitch
	{
		static public ADNTraceSwitch	Sw	            =	new ADNTraceSwitch("LoginTrace","Special Trace Switch for Login module");
	}
	#endregion Local TraceSwitch 

    public class LGST
    {
        public const string VisibleWhenLoggedIn     =   "LOGIN_VISIBLEWHENLOGGEDIN";
        public const string UseModuleTitle          =   "LOGIN_USEMODULETITLE";
        public const string PasswordRecoveryUrl     =   "LOGIN_PWD_RECOVERY_URL";
        public const string CreateUserUrl           =   "LOGIN_CREATE_USER_URL";
        public const string LoginViewVisible        =   "LOGIN_LOGINVIEW_VISIBLE";
        public const string UseImageButtonForLogin  =   "LOGIN_LOGINVIEW_USEIMAGEBUTTON";
        public const string LoginForceSSL           =   "LOGIN_FORCE_SSL";
        public const string AutoRedirect            =   "LOGIN_AUTOREDIRECT";
    }
        

    /// <summary>
    /// Initializer class for Login 
    /// </summary>
    public class LoginSI : PortalCRMModuleControlSI
    {
        public LoginSI(ModuleSettingsDictionary bSettings,ISettingsOwner pm) : base()
        {
            if ( ModuleTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]LoginSI Ctor BEG.",ModuleTraceSwitch.Sw.Info);
            InitSettings(bSettings,pm);
            if ( ModuleTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]LoginSI Ctor END.",ModuleTraceSwitch.Sw.Info);
        }
 
        public override void InitSettings(ModuleSettingsDictionary bSettings,ISettingsOwner pm)
        {             
            if ( ModuleTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]LoginSI InitSettings BEG.",ModuleTraceSwitch.Sw.Info);
            
            base.InitSettings(bSettings,pm);

            string    extgrp                        =   pm.ExtendedResourcesGroup;
            
            // Should login be displayed even after successfull login ( beware that login is always displayed when call from authentication prov directly)
            SettingItemSpecial VisibleWhenLoggedIn  =   new SettingItemSpecial(LGST.VisibleWhenLoggedIn,new BooleanDataType());
            VisibleWhenLoggedIn.Order               =   10;
            VisibleWhenLoggedIn.ExtendedGroupName   =   extgrp;
			VisibleWhenLoggedIn.Value               =   StStr.strFalse;
            VisibleWhenLoggedIn.EnglishName         =   "Visible When Logged In";
            VisibleWhenLoggedIn.Description         =   "Should the login component stay visible after successful login";
            bSettings.AddSetting(VisibleWhenLoggedIn);
            
            // Should login be displayed even after successfull login
            SettingItemSpecial UseModuleTitle       =   new SettingItemSpecial(LGST.UseModuleTitle,new BooleanDataType());
            UseModuleTitle.Order                    =   12;
            UseModuleTitle.ExtendedGroupName        =   extgrp;
			UseModuleTitle.Value                    =   StStr.strTrue;;
            UseModuleTitle.EnglishName              =   "Use module title";
            UseModuleTitle.Description              =   "Display module title in place of login title";
            bSettings.AddSetting(UseModuleTitle);

            SettingItemSpecial LoginViewVisible     =   new SettingItemSpecial(LGST.LoginViewVisible,new BooleanDataType());
            LoginViewVisible.Order                  =   15;
            LoginViewVisible.ExtendedGroupName      =   extgrp;
			LoginViewVisible.Value                  =   StStr.strTrue;;
            LoginViewVisible.EnglishName            =   "Login view";
            LoginViewVisible.Description            =   "Display login status view";
            bSettings.AddSetting(LoginViewVisible);

            SettingItemSpecial UseButtonForLogin    =   new SettingItemSpecial(LGST.UseImageButtonForLogin,new BooleanDataType());
            UseButtonForLogin.Order                 =   18;
            UseButtonForLogin.ExtendedGroupName     =   extgrp;
			UseButtonForLogin.Value                 =   StStr.strTrue;;
            UseButtonForLogin.EnglishName           =   "Login image button";
            UseButtonForLogin.Description           =   "Uses an imagebutton based on theme for login button when chcked, else use the default link or buttom from ascx code";
            bSettings.AddSetting(UseButtonForLogin);

            SettingItemSpecial PasswordRecoveryUrl  =   new SettingItemSpecial(LGST.PasswordRecoveryUrl,new StringDataType());
            PasswordRecoveryUrl.Order               =   20;
            PasswordRecoveryUrl.ExtendedGroupName   =   extgrp;
            if ( HttpContext.Current != null )
                PasswordRecoveryUrl.Value           =   HttpUrlBuilder.BuildUrl("~/recoverpwd.aspx",true,DynPageLoc.Login,StStr.PageRecoverPwdID);
            PasswordRecoveryUrl.EnglishName         =   "Password Recovery Url";
            PasswordRecoveryUrl.Description         =   "Url to navigate to recover password";
            bSettings.AddSetting(PasswordRecoveryUrl);
            
            SettingItemSpecial CreateUserUrl        =   new SettingItemSpecial(LGST.CreateUserUrl,new StringDataType());
            CreateUserUrl.Order                     =   30;
            CreateUserUrl.ExtendedGroupName         =   extgrp;
			// We must use a special PageID to load correct settings for page and register module
            if ( HttpContext.Current != null )
                CreateUserUrl.Value                 =   HttpUrlBuilder.BuildUrl("~/register.aspx",true,DynPageLoc.Login,StStr.RegisterPageID);
            CreateUserUrl.EnglishName               =   "Create User Url";
            CreateUserUrl.Description               =   "Url to navigate to create a new account";
            bSettings.AddSetting(CreateUserUrl);

            SettingItemSpecial LoginSSL             =   new SettingItemSpecial(LGST.LoginForceSSL,new BooleanDataType());
            LoginSSL.Order                          =   35;
            LoginSSL.ExtendedGroupName              =   extgrp;
			LoginSSL.Value                          =   StStr.strFalse;
            LoginSSL.EnglishName                    =   "Force SSL";
            LoginSSL.Description                    =   "Force SSL usage for page containing this module if site is ssl enabled from settings";
            bSettings.AddSetting(LoginSSL);

            SettingItemSpecial AutoRedirect         =   new SettingItemSpecial(LGST.AutoRedirect,new BooleanDataType());
            AutoRedirect.Order                      =   40;
            AutoRedirect.ExtendedGroupName          =   extgrp;
			AutoRedirect.Value                      =   StStr.strTrue;
            AutoRedirect.EnglishName                =   "Auto Redirect";
            AutoRedirect.Description                =   "Use last Url to redirect after successful login";
            bSettings.AddSetting(AutoRedirect);
            if ( ModuleTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]LoginSI InitSettings END.",ModuleTraceSwitch.Sw.Info);

        }
    }

    public partial class Login : PortalCRMModuleControl
    {
        /// <summary>
        /// No entity needed here
        /// </summary>
        public override bool NeedAttachedEntity
        {
            get
            {
                return false;
            }
        }

        #region General implementation
        public override Guid GuidID
        {
            get
            {
                return new Guid(StStr.LoginModuleGuid);
            }
        }
        #endregion General implementation

        #region Ctor and Initializer

        public Login()
        {
            if ( ModuleTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]Login Ctor Called.",ModuleTraceSwitch.Sw.Info);
        }

        public override string ExtendedResourcesGroup 
		{
            get
            {
                const string    extgrp                  =   "LOGIN";
                return extgrp;
            }
		}

        public override void InitPortalModuleControl(ModuleSettingsDictionary bSettings)
        {
            PortalModuleInitializer =   new LoginSI(bSettings,this);
        }

        #endregion Ctor
        
        protected void Page_Load(object sender, EventArgs e)
        {
            bool displayLogin           =   ( Config.AuthenticationMode == AuthenticationMode.Forms );

            if ( SecurityTraceSwitch.Sw.TraceVerbose || ModuleTraceSwitch.Sw.TraceVerbose || LoginTrace.Sw.TraceVerbose )
            {
                string info =   SecurityTraceSwitch.Sw.Info;
                if ( ModuleTraceSwitch.Sw.TraceVerbose )
                    info =   ModuleTraceSwitch.Sw.Info;
                else if (LoginTrace.Sw.TraceVerbose )
                    info =   LoginTrace.Sw.Info;
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]Login Page_Load BEG displayLogin : {0}, ReturnUrl: '{1}'",displayLogin,Request.QueryString["ReturnUrl"]),info);
            }
            Login1.Visible                          =   displayLogin;
            LoginView1.Visible                      =   Settings[LGST.LoginViewVisible].ToBool() & displayLogin;
            if ( !IsPostBack )
            {
                // pop the return url
                string str                          =   ADNPage.ReturnUrl;
                if (LoginTrace.Sw.TraceVerbose)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]Login Page_Load ReturnUrl: '{0}'.",str), LoginTrace.Sw.Info);
                string qstr                         =   Request.QueryString["ReturnUrl"];
                if (LoginTrace.Sw.TraceVerbose)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]Login Page_Load staked ReturnUrl: '{0}', Query ReturnUrl: '{1}'.",str,qstr), LoginTrace.Sw.Info);
                // and push again everything to prepare in case somebody call properties for this moduel
                if ( !string.IsNullOrEmpty(qstr) )
                    str                             =   qstr;
                ADNPage.ReturnUrl                   =   str;
                if ( Settings[LGST.AutoRedirect].ToBool() && !string.IsNullOrEmpty(str) )
                {
                    if (LoginTrace.Sw.TraceVerbose)
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]Login Page_Load DestinationPageUrl: '{0}'.",str), LoginTrace.Sw.Info);
                    Login1.DestinationPageUrl       =   str;
                    ViewState[StStr.strUrlReferrer] =   str;
                }
                Login1.LoginButtonType              =   ButtonType.Image;
                Login1.VisibleWhenLoggedIn          =   Settings[LGST.VisibleWhenLoggedIn].ToBool();
                Login1.PasswordRecoveryUrl          =   Settings[LGST.PasswordRecoveryUrl].Value;
                Login1.PasswordRecoveryText         =   LocalizeHelper.Localize("LOGIN_RECOVERPWD","Forgotten pwd ?");
    		    Login1.CreateUserUrl                =   Settings[LGST.CreateUserUrl].Value;
    		    Login1.CreateUserText               =   LocalizeHelper.Localize("LOGIN_CREATEUSER","Create account");
                Login1.FailureText                  =   LocalizeHelper.Localize("LOGIN_FAILURE","Your login attempt was not successfull. Please try again.");
                Login1.InstructionText              =   LocalizeHelper.Localize("LOGIN_INSTRUCTION","Enter username and password");
                Login1.PasswordLabelText            =   LocalizeHelper.Localize("LOGIN_PWD","Password :");
                if ( Settings[LGST.UseModuleTitle].ToBool() )
                        Login1.TitleText            =   TitleText;
                else Login1.TitleText               =   LocalizeHelper.Localize("LOGIN_TITLE","Login");
                Login1.UserNameRequiredErrorMessage =   LocalizeHelper.Localize("LOGIN_USERNAME_REQ","Name is required");
                Login1.RememberMeText               =   LocalizeHelper.Localize("LOGIN_REMEMBERME","Remember me next time");
                Login1.UserNameLabelText            =   LocalizeHelper.Localize("LOGIN_USERNAME","Name :");
            }
    		if (SecurityTraceSwitch.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]Login Page_Load END Login1.CreateUserUrl: {0}",Login1.CreateUserUrl),SecurityTraceSwitch.Sw.Info);

        }

        #region Std overrides

        public override void Page_PreInit(object sender,EventArgs e)
        {
            if ( Settings[LGST.UseImageButtonForLogin].ToBool() )
            {
                Login1.LoginButtonType              =   ButtonType.Image;
			    string strLoc			            =   Helpers.LocalizeHelper.GetCurrentNeutralCultureName();
                string SkinLogin                    =   string.Format("Login_{0}",strLoc);
                Login1.LoginButtonImageUrl          =   portalSettings.GetImageFromThemeSkins(SkinLogin);
            }
            base.Page_PreInit(sender,e);
        }

        override protected void OnInit(EventArgs e)
        {
    		if (ModuleTraceSwitch.Sw.TraceVerbose)
                Trace2.WriteLine("[V]Login OnInit BEG.",ModuleTraceSwitch.Sw.Info);
            // Force page recall with SLL if requested
            if ( ( !Request.IsSecureConnection )
                && Settings[LGST.LoginForceSSL].ToBool() && portalSettings.PortalIsSecured )
            {
    		    if (LoginTrace.Sw.TraceVerbose)
                    Trace2.WriteLine("[V]Login OnInit Forcing redirect to SSL.",LoginTrace.Sw.Info);
                Path.SwitchToSsl();
            }

            InitializeComponent();
    		if (ModuleTraceSwitch.Sw.TraceVerbose)
                Trace2.WriteLine("[V]Login OnInit END.",ModuleTraceSwitch.Sw.Info);
            base.OnInit(e);
        }

        private void InitializeComponent()
        {
            Load                            +=  new System.EventHandler(Page_Load);
            if ( Login1.MembershipProvider != AddonNiceMembershipProvider.ProviderClassName )
                Login1.MembershipProvider   =   AddonNiceMembershipProvider.ProviderClassName;
            Login1.Authenticate             +=  new AuthenticateEventHandler(Login1_Authenticate);
            Login1.LoggedIn                 +=  new EventHandler(Login1_LoggedIn);
        }


        void Login1_Authenticate(object sender, AuthenticateEventArgs e)
        {
    		if (SecurityTraceSwitch.Sw.TraceVerbose || LoginTrace.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]Login Login1_LoggedIn BEG Name: {0}",Login1.UserName),
                    (SecurityTraceSwitch.Sw.TraceVerbose) ? SecurityTraceSwitch.Sw.Info:LoginTrace.Sw.Info);
            
            e.Authenticated             =   false; 
            if (!Membership.ValidateUser(Login1.UserName, Login1.Password))
            {
    		    if (SecurityTraceSwitch.Sw.TraceVerbose || LoginTrace.Sw.TraceVerbose )
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]Login Login1_LoggedIn Enter Name: {0} Validate false", Login1.UserName),
                        (SecurityTraceSwitch.Sw.TraceVerbose) ? SecurityTraceSwitch.Sw.Info:LoginTrace.Sw.Info);
                Login1.InstructionText  =    LocalizeHelper.Localize("LOGIN_VALID_ACCOUNT","Enter a valid login/password");
            }
            else  e.Authenticated       =   true; 
        }

        /// <summary>
        /// Replace the created ticket with a new one containing our specific membership values
        /// </summary>
        void Login1_LoggedIn(object sender, EventArgs e)
        {
            HttpCookie cok                      =   Response.Cookies[FormsAuthentication.FormsCookieName];
    		if (SecurityTraceSwitch.Sw.TraceVerbose || LoginTrace.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]Global Login1_LoggedIn found cookie Expires: {0}, value: {1}", cok.Expires,cok.Value),
                    (SecurityTraceSwitch.Sw.TraceVerbose) ? SecurityTraceSwitch.Sw.Info:LoginTrace.Sw.Info);
            AddonNiceMembershipUser usr         =   (AddonNiceMembershipUser )   Membership.GetUser(Login1.UserName);
            string userData                     =   usr.UserData;
            if (SecurityTraceSwitch.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]Login Login1_LoggedIn replace cookie Name: {0} , UserData: {1}", Login1.UserName,userData),SecurityTraceSwitch.Sw.Info);
            Response.Cookies.Remove(FormsAuthentication.FormsCookieName);
            cok                      =   PortalSecurity.SetAuthCookie(Login1.UserName,userData,Login1.RememberMeSet);
            Response.Cookies.Add(cok);
            // Log a real login event
            PortalSecurity.Login(new AddonNiceIdentity(usr.UserName,usr.UserData));
    		if (SecurityTraceSwitch.Sw.TraceVerbose || LoginTrace.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]Login Login1_LoggedIn END Name: {0}", Login1.UserName),
                    (SecurityTraceSwitch.Sw.TraceVerbose) ? SecurityTraceSwitch.Sw.Info:LoginTrace.Sw.Info);
        } 
 
        #endregion

    }
}